#ifndef _APE_SERIALIZATION_ISINK_INCLUDED
#define _APE_SERIALIZATION_ISINK_INCLUDED

#include <stdlib.h>
#include <stdio.h>

namespace Ape {
	namespace Collections {
		template <typename Item_t>
		class Array;
	}
	namespace Serialization {
		class ISerializeable;

		/**
		 * Interface of a serialization sink
		 */
		class ISink {
		protected:
			virtual size_t SubmergeBytes(const Ape::Collections::Array<unsigned char>&) = 0;
			virtual void EmergeBytes(Ape::Collections::Array<unsigned char>&) = 0;

		private:
			size_t SubmergeRaw(const unsigned char* pData, size_t size);
			void EmergeRaw(unsigned char* pData, size_t size);

		public:
			template <typename Data_t>
			void SubmergeTyped(const Data_t& data) {
				//printf("generic submerge\n");
				const size_t size = sizeof(Data_t);
				const Data_t* pData = &data;
				const unsigned char* pBytes = (const unsigned char*)pData;
				SubmergeRaw(pBytes, size);
			}

			template <typename Data_t>
			void EmergeTyped(Data_t& data) {
				//printf("generic emerge\n");
				const size_t size = sizeof(Data_t);
				Data_t* pData = &data;
				unsigned char* pBytes = (unsigned char*)pData;
				EmergeRaw(pBytes, size);
			}

			void Submerge(const ISerializeable& object);
			void Emerge(ISerializeable& object);
			void Submerge(const ISerializeable* object);
			void Emerge(ISerializeable* object);
		};
	}
}

#endif // _APE_SERIALIZATION_ISINK_INCLUDED
